#ifndef _THREAD_H_
#define _THREAD_H_

#include <mutex>
#include <condition_variable>
#include <functional>

namespace zsylar
{
// 信号量类
class Semaphore
{
private:
    std::mutex mtx;
    std::condition_variable cv;
    int count;

public:
    // 构造函数 explicit:主要用于防止隐式类型转换
    explicit Semaphore(int count_ = 0) : count(count_){};

    // P操作（等待信号量）
    void wait()
    {
        std::unique_lock<std::mutex> lock(mtx);
        while (count == 0)
        {
            cv.wait(lock);  // 等待信号唤醒
        }
        count--;
    }

    // V操作（释放信号量）
    void signal()
    {
        std::unique_lock<std::mutex> lock(mtx);
        count++;
        cv.notify_one();
    }
};

class Thread
{
public:
    // 构造函数
    // @param cb 线程执行函数
    // @param name 线程名称
    Thread(std::function<void()> cb, const std::string& name);
    ~Thread();

    // 获取线程ID
    pid_t getId() const { return m_id; }
    // 获取线程名称
    const std::string& getName() const { return m_name; }

    // 等待线程结束
    void join();

public:
    // 获取线程ID
    static pid_t GetThreadId();
    // 获取当前线程指针对象
    static Thread* GetThis();

    // 获取当前线程名称
    // 添加static，表示该函数的作用域仅限于当前源文件（编译单元），其他文件无法访问。
    // 类内使用static：不依赖对象实例​；无this指针；可操作静态成员​
    static const std::string& GetName();

    // 设置当前线程名称
    static void SetName(const std::string& name);

private:
    // 线程入口函数
    static void* run(void* arg);

private:
    pid_t m_id = -1;        // 线程ID
    pthread_t m_thread = 0; // 线程句柄

    std::function<void()> m_cb; // 线程执行函数
    std::string m_name;         // 线程名称

    Semaphore m_semaphore;      // 用于线程初始化同步
};
}

#endif